#ifndef CONCURRENTALLOC_H
#define CONCURRENTALLOC_H

#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"

//线程调用申请内存
static void* ConcurrentAlloc(size_t size)
{
	//每个线程无锁的获取自己的专属ThreadCache对象
	if (size > MAX_BYTES)
	{
		size_t alignSize = SizeClass::RoupdUp(size);//对齐
		size_t kpage = alignSize >> PAGE_SHIFT;  //获取对应的页

		PageCache::GetInstance()->m_pageMtx.lock();
		Span* span = PageCache::GetInstance()->NewSpan(kpage);
		PageCache::GetInstance()->m_pageMtx.unlock();

		void* ptr = (void*)(span->pageId << PAGE_SHIFT);
		return ptr;
	}
	else
	{
		if (pTLSThreadCache == nullptr)
		{
			//pTLSThreadCache = new ThreadCache;
			static ObjectPool<ThreadCache> tcPool;
			pTLSThreadCache = tcPool.New();
		}
		return pTLSThreadCache->Allocate(size);
	}
}

//线程调用释放内存
static void ConcurrentFree(void* ptr)
{
	Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
	//还原内存大小
	size_t size = span->objSize;

	if (size > MAX_BYTES)
	{
		PageCache::GetInstance()->m_pageMtx.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(span);
		PageCache::GetInstance()->m_pageMtx.unlock();
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}
}

#endif